
from django_socketio.events import on_message
from wox.models import Machine, TestRunExec
from wox.log import LOGNFS, read_inst_log, read_test_log, get_logtype
from wox.const import LOG_TYPE_INST, LOG_TYPE_TEST, MSTATUS_UPDATE


@on_message(channel='^.')
def on_message_handler(request, socket, context, message):
    if 'channels' not in message:
        return

    # it's a channel-status dict
    csd = message['channels']
    ctype = ''
    try:
        ctype = get_logtype(csd.keys()[0])
    except IndexError:
        return

    data = []
    if ctype == LOG_TYPE_INST:
        # machine-status-c dict
        msd = {}
        # machine-channel dict
        mcd = {}
        for c in csd.keys():
            # get hostname
            h = c.split(LOGNFS)[1]
            msd[h] = csd[c]
            mcd[h] = c

        # machine queryset
        mqs = Machine.objects.filter(hostname__in=msd.keys()).only('status')
        for m in mqs:
            mstat = m.get_status_display()
            # just sync the logs whom status get changed
            if mstat != msd[m.hostname]:
                data.append({'channel': mcd[m.hostname],
                             'status': mstat,
                             'log': read_inst_log(m.hostname)})
    elif ctype == LOG_TYPE_TEST:
        # test-status-c dict
        tsd = {}
        # test-channel dict
        tcd = {}
        # test-machine dict
        tmd = {}
        for c in csd.keys():
            # get test id
            cf = c.split(LOGNFS)
            tid = int(cf[2])
            tsd[tid] = csd[c]
            tcd[tid] = c
            tmd[tid] = cf[1]

        # machine queryset
        tqs = TestRunExec.objects.filter(pk__in=tsd.keys()).only('status')
        for t in tqs:
            # just sync the logs whom status get changed
            tstat = t.get_status_display()
            if tstat != tsd[t.id]:
                data.append({'channel': tcd[t.id],
                             'status': tstat,
                             'log': read_test_log(tmd[t.id], t.id)})

    socket.send(data)

